package code;

/**
 * 描述:令牌桶算法实现
 *  1.定义初始容量capacity为当前桶的容量，timestamp为上一次请求令牌的时间
 *  2.没必要真实的实现用定时器每秒放入多少个令牌，只需要计算当前的时间戳和原先的时间戳差多少，然后放入令牌即可
 *  3.下面的代码假设100ms放入1个令牌，最大容量为10
 *
 * @author Madison You
 * @created 10:53
 */
public class LeakyBucketAlgorithm {

    private Integer capacity = 10;

    private Long timestamp = System.currentTimeMillis();

    public synchronized boolean getToken() {

        if (capacity > 0) {
            capacity--;
            return true;
        }

        Long currentTime = System.currentTimeMillis();
        if (currentTime - timestamp >= 100) {
            /*这边貌似有点问题，不知道是要不要+1*/
            capacity += (int) ((currentTime - timestamp) / 100);
            timestamp = currentTime;
            if (capacity >10) capacity = 10;
            return true;
        }

        return false;
    }

    public static void main(String[] args) throws Exception{
        LeakyBucketAlgorithm leakyBucketAlgorithm = new LeakyBucketAlgorithm();
        while (true) {
//            Thread.sleep(10);
            Thread.sleep(100);
            if (leakyBucketAlgorithm.getToken()) {
                System.out.println("获取令牌成功，可以执行业务逻辑了");
            } else {
                System.out.println("获取令牌失败，请稍后重试");
            }
        }
    }

}
